]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
11fdf7f2 TL |
3 | |
4 | #ifndef CEPH_RGW_ZONE_H | |
5 | #define CEPH_RGW_ZONE_H | |
6 | ||
7 | #include "rgw_common.h" | |
9f95a23c | 8 | #include "rgw_sync_policy.h" |
11fdf7f2 TL |
9 | |
10 | namespace rgw_zone_defaults { | |
11 | ||
12 | extern std::string zone_names_oid_prefix; | |
13 | extern std::string region_info_oid_prefix; | |
14 | extern std::string realm_names_oid_prefix; | |
15 | extern std::string zone_group_info_oid_prefix; | |
16 | extern std::string realm_info_oid_prefix; | |
17 | extern std::string default_region_info_oid; | |
18 | extern std::string default_zone_group_info_oid; | |
19 | extern std::string region_map_oid; | |
20 | extern std::string default_realm_info_oid; | |
21 | extern std::string default_zonegroup_name; | |
22 | extern std::string default_zone_name; | |
23 | extern std::string zonegroup_names_oid_prefix; | |
24 | extern std::string RGW_DEFAULT_ZONE_ROOT_POOL; | |
25 | extern std::string RGW_DEFAULT_ZONEGROUP_ROOT_POOL; | |
26 | extern std::string RGW_DEFAULT_REALM_ROOT_POOL; | |
27 | extern std::string RGW_DEFAULT_PERIOD_ROOT_POOL; | |
28 | extern std::string avail_pools; | |
29 | extern std::string default_storage_pool_suffix; | |
30 | ||
31 | } | |
32 | ||
33 | class JSONObj; | |
34 | class RGWSyncModulesManager; | |
35 | ||
9f95a23c | 36 | |
11fdf7f2 TL |
37 | struct RGWNameToId { |
38 | std::string obj_id; | |
39 | ||
40 | void encode(bufferlist& bl) const { | |
41 | ENCODE_START(1, 1, bl); | |
42 | encode(obj_id, bl); | |
43 | ENCODE_FINISH(bl); | |
44 | } | |
45 | ||
46 | void decode(bufferlist::const_iterator& bl) { | |
47 | DECODE_START(1, bl); | |
48 | decode(obj_id, bl); | |
49 | DECODE_FINISH(bl); | |
50 | } | |
51 | ||
52 | void dump(Formatter *f) const; | |
53 | void decode_json(JSONObj *obj); | |
54 | }; | |
55 | WRITE_CLASS_ENCODER(RGWNameToId) | |
56 | ||
57 | struct RGWDefaultSystemMetaObjInfo { | |
58 | std::string default_id; | |
59 | ||
60 | void encode(bufferlist& bl) const { | |
61 | ENCODE_START(1, 1, bl); | |
62 | encode(default_id, bl); | |
63 | ENCODE_FINISH(bl); | |
64 | } | |
65 | ||
66 | void decode(bufferlist::const_iterator& bl) { | |
67 | DECODE_START(1, bl); | |
68 | decode(default_id, bl); | |
69 | DECODE_FINISH(bl); | |
70 | } | |
71 | ||
72 | void dump(Formatter *f) const; | |
73 | void decode_json(JSONObj *obj); | |
74 | }; | |
75 | WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo) | |
76 | ||
77 | class RGWSI_SysObj; | |
78 | class RGWSI_Zone; | |
79 | ||
80 | class RGWSystemMetaObj { | |
81 | protected: | |
82 | std::string id; | |
83 | std::string name; | |
84 | ||
85 | CephContext *cct{nullptr}; | |
86 | RGWSI_SysObj *sysobj_svc{nullptr}; | |
87 | RGWSI_Zone *zone_svc{nullptr}; | |
88 | ||
b3b6e05e TL |
89 | int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y); |
90 | int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y); | |
91 | int read_info(const DoutPrefixProvider *dpp, const std::string& obj_id, optional_yield y, bool old_format = false); | |
92 | int read_id(const DoutPrefixProvider *dpp, const std::string& obj_name, std::string& obj_id, optional_yield y); | |
93 | int read_default(const DoutPrefixProvider *dpp, | |
94 | RGWDefaultSystemMetaObjInfo& default_info, | |
f67539c2 TL |
95 | const std::string& oid, |
96 | optional_yield y); | |
11fdf7f2 | 97 | /* read and use default id */ |
b3b6e05e | 98 | int use_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false); |
11fdf7f2 TL |
99 | |
100 | public: | |
101 | RGWSystemMetaObj() {} | |
102 | RGWSystemMetaObj(const std::string& _name): name(_name) {} | |
103 | RGWSystemMetaObj(const std::string& _id, const std::string& _name) : id(_id), name(_name) {} | |
104 | RGWSystemMetaObj(CephContext *_cct, RGWSI_SysObj *_sysobj_svc) { | |
105 | reinit_instance(_cct, _sysobj_svc); | |
106 | } | |
107 | RGWSystemMetaObj(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): name(_name) { | |
108 | reinit_instance(_cct, _sysobj_svc); | |
109 | } | |
110 | ||
111 | const std::string& get_name() const { return name; } | |
112 | const std::string& get_id() const { return id; } | |
113 | ||
114 | void set_name(const std::string& _name) { name = _name;} | |
115 | void set_id(const std::string& _id) { id = _id;} | |
116 | void clear_id() { id.clear(); } | |
117 | ||
118 | virtual ~RGWSystemMetaObj() {} | |
119 | ||
120 | virtual void encode(bufferlist& bl) const { | |
121 | ENCODE_START(1, 1, bl); | |
122 | encode(id, bl); | |
123 | encode(name, bl); | |
124 | ENCODE_FINISH(bl); | |
125 | } | |
126 | ||
127 | virtual void decode(bufferlist::const_iterator& bl) { | |
128 | DECODE_START(1, bl); | |
129 | decode(id, bl); | |
130 | decode(name, bl); | |
131 | DECODE_FINISH(bl); | |
132 | } | |
133 | ||
134 | void reinit_instance(CephContext *_cct, RGWSI_SysObj *_sysobj_svc); | |
b3b6e05e | 135 | int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, |
f67539c2 TL |
136 | optional_yield y, |
137 | bool setup_obj = true, bool old_format = false); | |
b3b6e05e | 138 | virtual int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, |
f67539c2 | 139 | bool old_format = false); |
b3b6e05e | 140 | virtual int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false); |
11fdf7f2 | 141 | int delete_default(); |
b3b6e05e TL |
142 | virtual int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true); |
143 | int delete_obj(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false); | |
144 | int rename(const DoutPrefixProvider *dpp, const std::string& new_name, optional_yield y); | |
145 | int update(const DoutPrefixProvider *dpp, optional_yield y) { return store_info(dpp, false, y);} | |
146 | int update_name(const DoutPrefixProvider *dpp, optional_yield y) { return store_name(dpp, false, y);} | |
147 | int read(const DoutPrefixProvider *dpp, optional_yield y); | |
148 | int write(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y); | |
11fdf7f2 TL |
149 | |
150 | virtual rgw_pool get_pool(CephContext *cct) const = 0; | |
151 | virtual const std::string get_default_oid(bool old_format = false) const = 0; | |
152 | virtual const std::string& get_names_oid_prefix() const = 0; | |
153 | virtual const std::string& get_info_oid_prefix(bool old_format = false) const = 0; | |
20effc67 | 154 | virtual std::string get_predefined_id(CephContext *cct) const = 0; |
11fdf7f2 TL |
155 | virtual const std::string& get_predefined_name(CephContext *cct) const = 0; |
156 | ||
157 | void dump(Formatter *f) const; | |
158 | void decode_json(JSONObj *obj); | |
159 | }; | |
160 | WRITE_CLASS_ENCODER(RGWSystemMetaObj) | |
161 | ||
162 | struct RGWZoneStorageClass { | |
163 | boost::optional<rgw_pool> data_pool; | |
164 | boost::optional<std::string> compression_type; | |
165 | ||
166 | void encode(bufferlist& bl) const { | |
167 | ENCODE_START(1, 1, bl); | |
168 | encode(data_pool, bl); | |
169 | encode(compression_type, bl); | |
170 | ENCODE_FINISH(bl); | |
171 | } | |
172 | ||
173 | void decode(bufferlist::const_iterator& bl) { | |
174 | DECODE_START(1, bl); | |
175 | decode(data_pool, bl); | |
176 | decode(compression_type, bl); | |
177 | DECODE_FINISH(bl); | |
178 | } | |
179 | ||
180 | void dump(Formatter *f) const; | |
181 | void decode_json(JSONObj *obj); | |
182 | }; | |
183 | WRITE_CLASS_ENCODER(RGWZoneStorageClass) | |
184 | ||
185 | ||
186 | class RGWZoneStorageClasses { | |
20effc67 | 187 | std::map<std::string, RGWZoneStorageClass> m; |
11fdf7f2 TL |
188 | |
189 | /* in memory only */ | |
190 | RGWZoneStorageClass *standard_class; | |
191 | ||
192 | public: | |
193 | RGWZoneStorageClasses() { | |
194 | standard_class = &m[RGW_STORAGE_CLASS_STANDARD]; | |
195 | } | |
196 | RGWZoneStorageClasses(const RGWZoneStorageClasses& rhs) { | |
197 | m = rhs.m; | |
198 | standard_class = &m[RGW_STORAGE_CLASS_STANDARD]; | |
199 | } | |
200 | RGWZoneStorageClasses& operator=(const RGWZoneStorageClasses& rhs) { | |
201 | m = rhs.m; | |
202 | standard_class = &m[RGW_STORAGE_CLASS_STANDARD]; | |
203 | return *this; | |
204 | } | |
205 | ||
206 | const RGWZoneStorageClass& get_standard() const { | |
207 | return *standard_class; | |
208 | } | |
209 | ||
20effc67 | 210 | bool find(const std::string& sc, const RGWZoneStorageClass **pstorage_class) const { |
11fdf7f2 TL |
211 | auto iter = m.find(sc); |
212 | if (iter == m.end()) { | |
213 | return false; | |
214 | } | |
215 | *pstorage_class = &iter->second; | |
216 | return true; | |
217 | } | |
218 | ||
20effc67 | 219 | bool exists(const std::string& sc) const { |
11fdf7f2 TL |
220 | if (sc.empty()) { |
221 | return true; | |
222 | } | |
223 | auto iter = m.find(sc); | |
224 | return (iter != m.end()); | |
225 | } | |
226 | ||
20effc67 | 227 | const std::map<std::string, RGWZoneStorageClass>& get_all() const { |
11fdf7f2 TL |
228 | return m; |
229 | } | |
230 | ||
20effc67 | 231 | std::map<std::string, RGWZoneStorageClass>& get_all() { |
11fdf7f2 TL |
232 | return m; |
233 | } | |
234 | ||
20effc67 TL |
235 | void set_storage_class(const std::string& sc, const rgw_pool *data_pool, const std::string *compression_type) { |
236 | const std::string *psc = ≻ | |
11fdf7f2 TL |
237 | if (sc.empty()) { |
238 | psc = &RGW_STORAGE_CLASS_STANDARD; | |
239 | } | |
240 | RGWZoneStorageClass& storage_class = m[*psc]; | |
241 | if (data_pool) { | |
242 | storage_class.data_pool = *data_pool; | |
243 | } | |
244 | if (compression_type) { | |
245 | storage_class.compression_type = *compression_type; | |
246 | } | |
247 | } | |
248 | ||
20effc67 | 249 | void remove_storage_class(const std::string& sc) { |
9f95a23c TL |
250 | if (!sc.empty()) { |
251 | m.erase(sc); | |
252 | } | |
253 | } | |
254 | ||
11fdf7f2 TL |
255 | void encode(bufferlist& bl) const { |
256 | ENCODE_START(1, 1, bl); | |
257 | encode(m, bl); | |
258 | ENCODE_FINISH(bl); | |
259 | } | |
260 | ||
261 | void decode(bufferlist::const_iterator& bl) { | |
262 | DECODE_START(1, bl); | |
263 | decode(m, bl); | |
264 | standard_class = &m[RGW_STORAGE_CLASS_STANDARD]; | |
265 | DECODE_FINISH(bl); | |
266 | } | |
267 | ||
268 | void dump(Formatter *f) const; | |
269 | void decode_json(JSONObj *obj); | |
270 | }; | |
271 | WRITE_CLASS_ENCODER(RGWZoneStorageClasses) | |
272 | ||
273 | struct RGWZonePlacementInfo { | |
274 | rgw_pool index_pool; | |
275 | rgw_pool data_extra_pool; /* if not set we should use data_pool */ | |
276 | RGWZoneStorageClasses storage_classes; | |
f67539c2 | 277 | rgw::BucketIndexType index_type; |
11fdf7f2 | 278 | |
f67539c2 | 279 | RGWZonePlacementInfo() : index_type(rgw::BucketIndexType::Normal) {} |
11fdf7f2 TL |
280 | |
281 | void encode(bufferlist& bl) const { | |
282 | ENCODE_START(7, 1, bl); | |
283 | encode(index_pool.to_str(), bl); | |
284 | rgw_pool standard_data_pool = get_data_pool(RGW_STORAGE_CLASS_STANDARD); | |
285 | encode(standard_data_pool.to_str(), bl); | |
286 | encode(data_extra_pool.to_str(), bl); | |
287 | encode((uint32_t)index_type, bl); | |
20effc67 | 288 | std::string standard_compression_type = get_compression_type(RGW_STORAGE_CLASS_STANDARD); |
11fdf7f2 TL |
289 | encode(standard_compression_type, bl); |
290 | encode(storage_classes, bl); | |
291 | ENCODE_FINISH(bl); | |
292 | } | |
293 | ||
294 | void decode(bufferlist::const_iterator& bl) { | |
295 | DECODE_START(7, bl); | |
20effc67 TL |
296 | std::string index_pool_str; |
297 | std::string data_pool_str; | |
11fdf7f2 TL |
298 | decode(index_pool_str, bl); |
299 | index_pool = rgw_pool(index_pool_str); | |
300 | decode(data_pool_str, bl); | |
301 | rgw_pool standard_data_pool(data_pool_str); | |
302 | if (struct_v >= 4) { | |
20effc67 | 303 | std::string data_extra_pool_str; |
11fdf7f2 TL |
304 | decode(data_extra_pool_str, bl); |
305 | data_extra_pool = rgw_pool(data_extra_pool_str); | |
306 | } | |
307 | if (struct_v >= 5) { | |
308 | uint32_t it; | |
309 | decode(it, bl); | |
f67539c2 | 310 | index_type = (rgw::BucketIndexType)it; |
11fdf7f2 | 311 | } |
20effc67 | 312 | std::string standard_compression_type; |
11fdf7f2 TL |
313 | if (struct_v >= 6) { |
314 | decode(standard_compression_type, bl); | |
315 | } | |
316 | if (struct_v >= 7) { | |
317 | decode(storage_classes, bl); | |
318 | } else { | |
319 | storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &standard_data_pool, | |
320 | (!standard_compression_type.empty() ? &standard_compression_type : nullptr)); | |
321 | } | |
322 | DECODE_FINISH(bl); | |
323 | } | |
324 | const rgw_pool& get_data_extra_pool() const { | |
325 | static rgw_pool no_pool; | |
326 | if (data_extra_pool.empty()) { | |
327 | return storage_classes.get_standard().data_pool.get_value_or(no_pool); | |
328 | } | |
329 | return data_extra_pool; | |
330 | } | |
20effc67 | 331 | const rgw_pool& get_data_pool(const std::string& sc) const { |
11fdf7f2 TL |
332 | const RGWZoneStorageClass *storage_class; |
333 | static rgw_pool no_pool; | |
334 | ||
335 | if (!storage_classes.find(sc, &storage_class)) { | |
336 | return storage_classes.get_standard().data_pool.get_value_or(no_pool); | |
337 | } | |
338 | ||
339 | return storage_class->data_pool.get_value_or(no_pool); | |
340 | } | |
341 | const rgw_pool& get_standard_data_pool() const { | |
342 | return get_data_pool(RGW_STORAGE_CLASS_STANDARD); | |
343 | } | |
344 | ||
20effc67 | 345 | const std::string& get_compression_type(const std::string& sc) const { |
11fdf7f2 | 346 | const RGWZoneStorageClass *storage_class; |
20effc67 | 347 | static std::string no_compression; |
11fdf7f2 TL |
348 | |
349 | if (!storage_classes.find(sc, &storage_class)) { | |
350 | return no_compression; | |
351 | } | |
352 | return storage_class->compression_type.get_value_or(no_compression); | |
353 | } | |
354 | ||
20effc67 | 355 | bool storage_class_exists(const std::string& sc) const { |
11fdf7f2 TL |
356 | return storage_classes.exists(sc); |
357 | } | |
358 | ||
359 | void dump(Formatter *f) const; | |
360 | void decode_json(JSONObj *obj); | |
361 | ||
362 | }; | |
363 | WRITE_CLASS_ENCODER(RGWZonePlacementInfo) | |
364 | ||
365 | struct RGWZoneParams : RGWSystemMetaObj { | |
366 | rgw_pool domain_root; | |
11fdf7f2 TL |
367 | rgw_pool control_pool; |
368 | rgw_pool gc_pool; | |
369 | rgw_pool lc_pool; | |
370 | rgw_pool log_pool; | |
371 | rgw_pool intent_log_pool; | |
372 | rgw_pool usage_log_pool; | |
373 | ||
374 | rgw_pool user_keys_pool; | |
375 | rgw_pool user_email_pool; | |
376 | rgw_pool user_swift_pool; | |
377 | rgw_pool user_uid_pool; | |
378 | rgw_pool roles_pool; | |
379 | rgw_pool reshard_pool; | |
380 | rgw_pool otp_pool; | |
f91f0fd5 | 381 | rgw_pool oidc_pool; |
11fdf7f2 TL |
382 | |
383 | RGWAccessKey system_key; | |
384 | ||
20effc67 | 385 | std::map<std::string, RGWZonePlacementInfo> placement_pools; |
11fdf7f2 TL |
386 | |
387 | std::string realm_id; | |
388 | ||
389 | JSONFormattable tier_config; | |
390 | ||
f67539c2 TL |
391 | rgw_pool notif_pool; |
392 | ||
11fdf7f2 TL |
393 | RGWZoneParams() : RGWSystemMetaObj() {} |
394 | explicit RGWZoneParams(const std::string& name) : RGWSystemMetaObj(name){} | |
9f95a23c TL |
395 | RGWZoneParams(const rgw_zone_id& id, const std::string& name) : RGWSystemMetaObj(id.id, name) {} |
396 | RGWZoneParams(const rgw_zone_id& id, const std::string& name, const std::string& _realm_id) | |
397 | : RGWSystemMetaObj(id.id, name), realm_id(_realm_id) {} | |
11fdf7f2 TL |
398 | |
399 | rgw_pool get_pool(CephContext *cct) const override; | |
400 | const std::string get_default_oid(bool old_format = false) const override; | |
401 | const std::string& get_names_oid_prefix() const override; | |
402 | const std::string& get_info_oid_prefix(bool old_format = false) const override; | |
20effc67 | 403 | std::string get_predefined_id(CephContext *cct) const override; |
11fdf7f2 TL |
404 | const std::string& get_predefined_name(CephContext *cct) const override; |
405 | ||
b3b6e05e TL |
406 | int init(const DoutPrefixProvider *dpp, |
407 | CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y, | |
f67539c2 | 408 | bool setup_obj = true, bool old_format = false); |
11fdf7f2 | 409 | using RGWSystemMetaObj::init; |
b3b6e05e TL |
410 | int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override; |
411 | int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override; | |
412 | int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false); | |
413 | int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override; | |
414 | int fix_pool_names(const DoutPrefixProvider *dpp, optional_yield y); | |
11fdf7f2 | 415 | |
20effc67 | 416 | const std::string& get_compression_type(const rgw_placement_rule& placement_rule) const; |
11fdf7f2 TL |
417 | |
418 | void encode(bufferlist& bl) const override { | |
f67539c2 | 419 | ENCODE_START(14, 1, bl); |
11fdf7f2 TL |
420 | encode(domain_root, bl); |
421 | encode(control_pool, bl); | |
422 | encode(gc_pool, bl); | |
423 | encode(log_pool, bl); | |
424 | encode(intent_log_pool, bl); | |
425 | encode(usage_log_pool, bl); | |
426 | encode(user_keys_pool, bl); | |
427 | encode(user_email_pool, bl); | |
428 | encode(user_swift_pool, bl); | |
429 | encode(user_uid_pool, bl); | |
430 | RGWSystemMetaObj::encode(bl); | |
431 | encode(system_key, bl); | |
432 | encode(placement_pools, bl); | |
9f95a23c TL |
433 | rgw_pool unused_metadata_heap; |
434 | encode(unused_metadata_heap, bl); | |
11fdf7f2 TL |
435 | encode(realm_id, bl); |
436 | encode(lc_pool, bl); | |
20effc67 | 437 | std::map<std::string, std::string, ltstr_nocase> old_tier_config; |
11fdf7f2 TL |
438 | encode(old_tier_config, bl); |
439 | encode(roles_pool, bl); | |
440 | encode(reshard_pool, bl); | |
441 | encode(otp_pool, bl); | |
442 | encode(tier_config, bl); | |
f91f0fd5 | 443 | encode(oidc_pool, bl); |
f67539c2 | 444 | encode(notif_pool, bl); |
11fdf7f2 TL |
445 | ENCODE_FINISH(bl); |
446 | } | |
447 | ||
448 | void decode(bufferlist::const_iterator& bl) override { | |
f67539c2 | 449 | DECODE_START(14, bl); |
11fdf7f2 TL |
450 | decode(domain_root, bl); |
451 | decode(control_pool, bl); | |
452 | decode(gc_pool, bl); | |
453 | decode(log_pool, bl); | |
454 | decode(intent_log_pool, bl); | |
455 | decode(usage_log_pool, bl); | |
456 | decode(user_keys_pool, bl); | |
457 | decode(user_email_pool, bl); | |
458 | decode(user_swift_pool, bl); | |
459 | decode(user_uid_pool, bl); | |
460 | if (struct_v >= 6) { | |
461 | RGWSystemMetaObj::decode(bl); | |
462 | } else if (struct_v >= 2) { | |
463 | decode(name, bl); | |
464 | id = name; | |
465 | } | |
466 | if (struct_v >= 3) | |
467 | decode(system_key, bl); | |
468 | if (struct_v >= 4) | |
469 | decode(placement_pools, bl); | |
9f95a23c TL |
470 | if (struct_v >= 5) { |
471 | rgw_pool unused_metadata_heap; | |
472 | decode(unused_metadata_heap, bl); | |
473 | } | |
11fdf7f2 TL |
474 | if (struct_v >= 6) { |
475 | decode(realm_id, bl); | |
476 | } | |
477 | if (struct_v >= 7) { | |
478 | decode(lc_pool, bl); | |
479 | } else { | |
480 | lc_pool = log_pool.name + ":lc"; | |
481 | } | |
20effc67 | 482 | std::map<std::string, std::string, ltstr_nocase> old_tier_config; |
11fdf7f2 TL |
483 | if (struct_v >= 8) { |
484 | decode(old_tier_config, bl); | |
485 | } | |
486 | if (struct_v >= 9) { | |
487 | decode(roles_pool, bl); | |
488 | } else { | |
489 | roles_pool = name + ".rgw.meta:roles"; | |
490 | } | |
491 | if (struct_v >= 10) { | |
492 | decode(reshard_pool, bl); | |
493 | } else { | |
494 | reshard_pool = log_pool.name + ":reshard"; | |
495 | } | |
496 | if (struct_v >= 11) { | |
497 | ::decode(otp_pool, bl); | |
498 | } else { | |
499 | otp_pool = name + ".rgw.otp"; | |
500 | } | |
501 | if (struct_v >= 12) { | |
502 | ::decode(tier_config, bl); | |
503 | } else { | |
504 | for (auto& kv : old_tier_config) { | |
505 | tier_config.set(kv.first, kv.second); | |
506 | } | |
507 | } | |
f91f0fd5 TL |
508 | if (struct_v >= 13) { |
509 | ::decode(oidc_pool, bl); | |
510 | } else { | |
511 | oidc_pool = name + ".rgw.meta:oidc"; | |
512 | } | |
f67539c2 TL |
513 | if (struct_v >= 14) { |
514 | decode(notif_pool, bl); | |
515 | } else { | |
516 | notif_pool = log_pool.name + ":notif"; | |
517 | } | |
11fdf7f2 TL |
518 | DECODE_FINISH(bl); |
519 | } | |
520 | void dump(Formatter *f) const; | |
521 | void decode_json(JSONObj *obj); | |
20effc67 | 522 | static void generate_test_instances(std::list<RGWZoneParams*>& o); |
11fdf7f2 TL |
523 | |
524 | bool get_placement(const std::string& placement_id, RGWZonePlacementInfo *placement) const { | |
525 | auto iter = placement_pools.find(placement_id); | |
526 | if (iter == placement_pools.end()) { | |
527 | return false; | |
528 | } | |
529 | *placement = iter->second; | |
530 | return true; | |
531 | } | |
532 | ||
533 | /* | |
534 | * return data pool of the head object | |
535 | */ | |
536 | bool get_head_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool) const { | |
537 | const rgw_data_placement_target& explicit_placement = obj.bucket.explicit_placement; | |
538 | if (!explicit_placement.data_pool.empty()) { | |
539 | if (!obj.in_extra_data) { | |
540 | *pool = explicit_placement.data_pool; | |
541 | } else { | |
542 | *pool = explicit_placement.get_data_extra_pool(); | |
543 | } | |
544 | return true; | |
545 | } | |
546 | if (placement_rule.empty()) { | |
547 | return false; | |
548 | } | |
549 | auto iter = placement_pools.find(placement_rule.name); | |
550 | if (iter == placement_pools.end()) { | |
551 | return false; | |
552 | } | |
553 | if (!obj.in_extra_data) { | |
554 | *pool = iter->second.get_data_pool(placement_rule.storage_class); | |
555 | } else { | |
556 | *pool = iter->second.get_data_extra_pool(); | |
557 | } | |
558 | return true; | |
559 | } | |
560 | ||
561 | bool valid_placement(const rgw_placement_rule& rule) const { | |
562 | auto iter = placement_pools.find(rule.name); | |
563 | if (iter == placement_pools.end()) { | |
564 | return false; | |
565 | } | |
566 | return iter->second.storage_class_exists(rule.storage_class); | |
567 | } | |
568 | }; | |
569 | WRITE_CLASS_ENCODER(RGWZoneParams) | |
570 | ||
571 | struct RGWZone { | |
572 | std::string id; | |
573 | std::string name; | |
20effc67 | 574 | std::list<std::string> endpoints; |
11fdf7f2 TL |
575 | bool log_meta; |
576 | bool log_data; | |
577 | bool read_only; | |
578 | std::string tier_type; | |
579 | ||
580 | std::string redirect_zone; | |
581 | ||
582 | /** | |
583 | * Represents the number of shards for the bucket index object, a value of zero | |
584 | * indicates there is no sharding. By default (no sharding, the name of the object | |
585 | * is '.dir.{marker}', with sharding, the name is '.dir.{marker}.{sharding_id}', | |
586 | * sharding_id is zero-based value. It is not recommended to set a too large value | |
587 | * (e.g. thousand) as it increases the cost for bucket listing. | |
588 | */ | |
589 | uint32_t bucket_index_max_shards; | |
590 | ||
9f95a23c TL |
591 | // pre-shard buckets on creation to enable some write-parallism by default, |
592 | // delay the need to reshard as the bucket grows, and (in multisite) get some | |
593 | // bucket index sharding where dynamic resharding is not supported | |
594 | static constexpr uint32_t default_bucket_index_max_shards = 11; | |
595 | ||
11fdf7f2 | 596 | bool sync_from_all; |
20effc67 | 597 | std::set<std::string> sync_from; /* list of zones to sync from */ |
11fdf7f2 | 598 | |
9f95a23c TL |
599 | RGWZone() |
600 | : log_meta(false), log_data(false), read_only(false), | |
601 | bucket_index_max_shards(default_bucket_index_max_shards), | |
602 | sync_from_all(true) {} | |
11fdf7f2 TL |
603 | |
604 | void encode(bufferlist& bl) const { | |
605 | ENCODE_START(7, 1, bl); | |
606 | encode(name, bl); | |
607 | encode(endpoints, bl); | |
608 | encode(log_meta, bl); | |
609 | encode(log_data, bl); | |
610 | encode(bucket_index_max_shards, bl); | |
611 | encode(id, bl); | |
612 | encode(read_only, bl); | |
613 | encode(tier_type, bl); | |
614 | encode(sync_from_all, bl); | |
615 | encode(sync_from, bl); | |
616 | encode(redirect_zone, bl); | |
617 | ENCODE_FINISH(bl); | |
618 | } | |
619 | ||
620 | void decode(bufferlist::const_iterator& bl) { | |
621 | DECODE_START(7, bl); | |
622 | decode(name, bl); | |
623 | if (struct_v < 4) { | |
624 | id = name; | |
625 | } | |
626 | decode(endpoints, bl); | |
627 | if (struct_v >= 2) { | |
628 | decode(log_meta, bl); | |
629 | decode(log_data, bl); | |
630 | } | |
631 | if (struct_v >= 3) { | |
632 | decode(bucket_index_max_shards, bl); | |
633 | } | |
634 | if (struct_v >= 4) { | |
635 | decode(id, bl); | |
636 | decode(read_only, bl); | |
637 | } | |
638 | if (struct_v >= 5) { | |
639 | decode(tier_type, bl); | |
640 | } | |
641 | if (struct_v >= 6) { | |
642 | decode(sync_from_all, bl); | |
643 | decode(sync_from, bl); | |
644 | } | |
645 | if (struct_v >= 7) { | |
646 | decode(redirect_zone, bl); | |
647 | } | |
648 | DECODE_FINISH(bl); | |
649 | } | |
650 | void dump(Formatter *f) const; | |
651 | void decode_json(JSONObj *obj); | |
20effc67 | 652 | static void generate_test_instances(std::list<RGWZone*>& o); |
11fdf7f2 TL |
653 | |
654 | bool is_read_only() const { return read_only; } | |
655 | ||
494da23a TL |
656 | bool syncs_from(const std::string& zone_name) const { |
657 | return (sync_from_all || sync_from.find(zone_name) != sync_from.end()); | |
11fdf7f2 TL |
658 | } |
659 | }; | |
660 | WRITE_CLASS_ENCODER(RGWZone) | |
661 | ||
662 | struct RGWDefaultZoneGroupInfo { | |
663 | std::string default_zonegroup; | |
664 | ||
665 | void encode(bufferlist& bl) const { | |
666 | ENCODE_START(1, 1, bl); | |
667 | encode(default_zonegroup, bl); | |
668 | ENCODE_FINISH(bl); | |
669 | } | |
670 | ||
671 | void decode(bufferlist::const_iterator& bl) { | |
672 | DECODE_START(1, bl); | |
673 | decode(default_zonegroup, bl); | |
674 | DECODE_FINISH(bl); | |
675 | } | |
676 | void dump(Formatter *f) const; | |
677 | void decode_json(JSONObj *obj); | |
678 | //todo: implement ceph-dencoder | |
679 | }; | |
680 | WRITE_CLASS_ENCODER(RGWDefaultZoneGroupInfo) | |
681 | ||
20effc67 TL |
682 | struct RGWTierACLMapping { |
683 | ACLGranteeTypeEnum type{ACL_TYPE_CANON_USER}; | |
684 | std::string source_id; | |
685 | std::string dest_id; | |
686 | ||
687 | RGWTierACLMapping() = default; | |
688 | ||
689 | RGWTierACLMapping(ACLGranteeTypeEnum t, | |
690 | const std::string& s, | |
691 | const std::string& d) : type(t), | |
692 | source_id(s), | |
693 | dest_id(d) {} | |
694 | ||
695 | void init(const JSONFormattable& config) { | |
696 | const std::string& t = config["type"]; | |
697 | ||
698 | if (t == "email") { | |
699 | type = ACL_TYPE_EMAIL_USER; | |
700 | } else if (t == "uri") { | |
701 | type = ACL_TYPE_GROUP; | |
702 | } else { | |
703 | type = ACL_TYPE_CANON_USER; | |
704 | } | |
705 | ||
706 | source_id = config["source_id"]; | |
707 | dest_id = config["dest_id"]; | |
708 | } | |
709 | ||
710 | void encode(bufferlist& bl) const { | |
711 | ENCODE_START(1, 1, bl); | |
712 | encode((uint32_t)type, bl); | |
713 | encode(source_id, bl); | |
714 | encode(dest_id, bl); | |
715 | ENCODE_FINISH(bl); | |
716 | } | |
717 | ||
718 | void decode(bufferlist::const_iterator& bl) { | |
719 | DECODE_START(1, bl); | |
720 | uint32_t it; | |
721 | decode(it, bl); | |
722 | type = (ACLGranteeTypeEnum)it; | |
723 | decode(source_id, bl); | |
724 | decode(dest_id, bl); | |
725 | DECODE_FINISH(bl); | |
726 | } | |
727 | void dump(Formatter *f) const; | |
728 | void decode_json(JSONObj *obj); | |
729 | }; | |
730 | WRITE_CLASS_ENCODER(RGWTierACLMapping) | |
731 | ||
732 | struct RGWZoneGroupPlacementTierS3 { | |
733 | #define DEFAULT_MULTIPART_SYNC_PART_SIZE (32 * 1024 * 1024) | |
734 | std::string endpoint; | |
735 | RGWAccessKey key; | |
736 | std::string region; | |
737 | HostStyle host_style{PathStyle}; | |
738 | std::string target_storage_class; | |
739 | ||
740 | /* Should below be bucket/zone specific?? */ | |
741 | std::string target_path; | |
742 | std::map<std::string, RGWTierACLMapping> acl_mappings; | |
743 | ||
744 | uint64_t multipart_sync_threshold{DEFAULT_MULTIPART_SYNC_PART_SIZE}; | |
745 | uint64_t multipart_min_part_size{DEFAULT_MULTIPART_SYNC_PART_SIZE}; | |
746 | ||
747 | int update_params(const JSONFormattable& config); | |
748 | int clear_params(const JSONFormattable& config); | |
749 | ||
750 | void encode(bufferlist& bl) const { | |
751 | ENCODE_START(1, 1, bl); | |
752 | encode(endpoint, bl); | |
753 | encode(key, bl); | |
754 | encode(region, bl); | |
755 | encode((uint32_t)host_style, bl); | |
756 | encode(target_storage_class, bl); | |
757 | encode(target_path, bl); | |
758 | encode(acl_mappings, bl); | |
759 | encode(multipart_sync_threshold, bl); | |
760 | encode(multipart_min_part_size, bl); | |
761 | ENCODE_FINISH(bl); | |
762 | } | |
763 | ||
764 | void decode(bufferlist::const_iterator& bl) { | |
765 | DECODE_START(1, bl); | |
766 | decode(endpoint, bl); | |
767 | decode(key, bl); | |
768 | decode(region, bl); | |
769 | ||
770 | uint32_t it; | |
771 | decode(it, bl); | |
772 | host_style = (HostStyle)it; | |
773 | ||
774 | decode(target_storage_class, bl); | |
775 | decode(target_path, bl); | |
776 | decode(acl_mappings, bl); | |
777 | decode(multipart_sync_threshold, bl); | |
778 | decode(multipart_min_part_size, bl); | |
779 | DECODE_FINISH(bl); | |
780 | } | |
781 | void dump(Formatter *f) const; | |
782 | void decode_json(JSONObj *obj); | |
783 | }; | |
784 | WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTierS3) | |
785 | ||
786 | struct RGWZoneGroupPlacementTier { | |
787 | std::string tier_type; | |
788 | std::string storage_class; | |
789 | bool retain_head_object = false; | |
790 | ||
791 | struct _tier { | |
792 | RGWZoneGroupPlacementTierS3 s3; | |
793 | } t; | |
794 | ||
795 | int update_params(const JSONFormattable& config); | |
796 | int clear_params(const JSONFormattable& config); | |
797 | ||
798 | void encode(bufferlist& bl) const { | |
799 | ENCODE_START(1, 1, bl); | |
800 | encode(tier_type, bl); | |
801 | encode(storage_class, bl); | |
802 | encode(retain_head_object, bl); | |
803 | if (tier_type == "cloud-s3") { | |
804 | encode(t.s3, bl); | |
805 | } | |
806 | ENCODE_FINISH(bl); | |
807 | } | |
808 | ||
809 | void decode(bufferlist::const_iterator& bl) { | |
810 | DECODE_START(1, bl); | |
811 | decode(tier_type, bl); | |
812 | decode(storage_class, bl); | |
813 | decode(retain_head_object, bl); | |
814 | if (tier_type == "cloud-s3") { | |
815 | decode(t.s3, bl); | |
816 | } | |
817 | DECODE_FINISH(bl); | |
818 | } | |
819 | ||
820 | void dump(Formatter *f) const; | |
821 | void decode_json(JSONObj *obj); | |
822 | }; | |
823 | WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTier) | |
824 | ||
11fdf7f2 TL |
825 | struct RGWZoneGroupPlacementTarget { |
826 | std::string name; | |
20effc67 TL |
827 | std::set<std::string> tags; |
828 | std::set<std::string> storage_classes; | |
829 | std::map<std::string, RGWZoneGroupPlacementTier> tier_targets; | |
11fdf7f2 | 830 | |
20effc67 | 831 | bool user_permitted(const std::list<std::string>& user_tags) const { |
11fdf7f2 TL |
832 | if (tags.empty()) { |
833 | return true; | |
834 | } | |
835 | for (auto& rule : user_tags) { | |
836 | if (tags.find(rule) != tags.end()) { | |
837 | return true; | |
838 | } | |
839 | } | |
840 | return false; | |
841 | } | |
842 | ||
843 | void encode(bufferlist& bl) const { | |
20effc67 | 844 | ENCODE_START(3, 1, bl); |
11fdf7f2 TL |
845 | encode(name, bl); |
846 | encode(tags, bl); | |
847 | encode(storage_classes, bl); | |
20effc67 | 848 | encode(tier_targets, bl); |
11fdf7f2 TL |
849 | ENCODE_FINISH(bl); |
850 | } | |
851 | ||
852 | void decode(bufferlist::const_iterator& bl) { | |
20effc67 | 853 | DECODE_START(3, bl); |
11fdf7f2 TL |
854 | decode(name, bl); |
855 | decode(tags, bl); | |
856 | if (struct_v >= 2) { | |
857 | decode(storage_classes, bl); | |
858 | } | |
859 | if (storage_classes.empty()) { | |
860 | storage_classes.insert(RGW_STORAGE_CLASS_STANDARD); | |
861 | } | |
20effc67 TL |
862 | if (struct_v >= 3) { |
863 | decode(tier_targets, bl); | |
864 | } | |
11fdf7f2 TL |
865 | DECODE_FINISH(bl); |
866 | } | |
867 | void dump(Formatter *f) const; | |
868 | void decode_json(JSONObj *obj); | |
869 | }; | |
870 | WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTarget) | |
871 | ||
872 | struct RGWZoneGroup : public RGWSystemMetaObj { | |
873 | std::string api_name; | |
20effc67 | 874 | std::list<std::string> endpoints; |
11fdf7f2 TL |
875 | bool is_master = false; |
876 | ||
9f95a23c | 877 | rgw_zone_id master_zone; |
20effc67 | 878 | std::map<rgw_zone_id, RGWZone> zones; |
11fdf7f2 | 879 | |
20effc67 | 880 | std::map<std::string, RGWZoneGroupPlacementTarget> placement_targets; |
11fdf7f2 TL |
881 | rgw_placement_rule default_placement; |
882 | ||
20effc67 TL |
883 | std::list<std::string> hostnames; |
884 | std::list<std::string> hostnames_s3website; | |
885 | // TODO: Maybe convert hostnames to a map<std::string,std::list<std::string>> for | |
11fdf7f2 TL |
886 | // endpoint_type->hostnames |
887 | /* | |
888 | 20:05 < _robbat21irssi> maybe I do someting like: if (hostname_map.empty()) { populate all map keys from hostnames; }; | |
889 | 20:05 < _robbat21irssi> but that's a later compatability migration planning bit | |
890 | 20:06 < yehudasa> more like if (!hostnames.empty()) { | |
20effc67 | 891 | 20:06 < yehudasa> for (std::list<std::string>::iterator iter = hostnames.begin(); iter != hostnames.end(); ++iter) { |
11fdf7f2 TL |
892 | 20:06 < yehudasa> hostname_map["s3"].append(iter->second); |
893 | 20:07 < yehudasa> hostname_map["s3website"].append(iter->second); | |
894 | 20:07 < yehudasa> s/append/push_back/g | |
895 | 20:08 < _robbat21irssi> inner loop over APIs | |
896 | 20:08 < yehudasa> yeah, probably | |
897 | 20:08 < _robbat21irssi> s3, s3website, swift, swith_auth, swift_website | |
898 | */ | |
20effc67 TL |
899 | std::map<std::string, std::list<std::string> > api_hostname_map; |
900 | std::map<std::string, std::list<std::string> > api_endpoints_map; | |
11fdf7f2 TL |
901 | |
902 | std::string realm_id; | |
903 | ||
9f95a23c TL |
904 | rgw_sync_policy_info sync_policy; |
905 | ||
11fdf7f2 TL |
906 | RGWZoneGroup(): is_master(false){} |
907 | RGWZoneGroup(const std::string &id, const std::string &name):RGWSystemMetaObj(id, name) {} | |
908 | explicit RGWZoneGroup(const std::string &_name):RGWSystemMetaObj(_name) {} | |
909 | RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWSI_SysObj* sysobj_svc, | |
20effc67 | 910 | const std::string& _realm_id, const std::list<std::string>& _endpoints) |
11fdf7f2 TL |
911 | : RGWSystemMetaObj(_name, cct , sysobj_svc), endpoints(_endpoints), is_master(_is_master), |
912 | realm_id(_realm_id) {} | |
913 | ||
914 | bool is_master_zonegroup() const { return is_master;} | |
b3b6e05e | 915 | void update_master(const DoutPrefixProvider *dpp, bool _is_master, optional_yield y) { |
11fdf7f2 | 916 | is_master = _is_master; |
b3b6e05e | 917 | post_process_params(dpp, y); |
11fdf7f2 | 918 | } |
b3b6e05e | 919 | void post_process_params(const DoutPrefixProvider *dpp, optional_yield y); |
11fdf7f2 TL |
920 | |
921 | void encode(bufferlist& bl) const override { | |
9f95a23c | 922 | ENCODE_START(5, 1, bl); |
11fdf7f2 TL |
923 | encode(name, bl); |
924 | encode(api_name, bl); | |
925 | encode(is_master, bl); | |
926 | encode(endpoints, bl); | |
927 | encode(master_zone, bl); | |
928 | encode(zones, bl); | |
929 | encode(placement_targets, bl); | |
930 | encode(default_placement, bl); | |
931 | encode(hostnames, bl); | |
932 | encode(hostnames_s3website, bl); | |
933 | RGWSystemMetaObj::encode(bl); | |
934 | encode(realm_id, bl); | |
9f95a23c | 935 | encode(sync_policy, bl); |
11fdf7f2 TL |
936 | ENCODE_FINISH(bl); |
937 | } | |
938 | ||
939 | void decode(bufferlist::const_iterator& bl) override { | |
9f95a23c | 940 | DECODE_START(5, bl); |
11fdf7f2 TL |
941 | decode(name, bl); |
942 | decode(api_name, bl); | |
943 | decode(is_master, bl); | |
944 | decode(endpoints, bl); | |
945 | decode(master_zone, bl); | |
946 | decode(zones, bl); | |
947 | decode(placement_targets, bl); | |
948 | decode(default_placement, bl); | |
949 | if (struct_v >= 2) { | |
950 | decode(hostnames, bl); | |
951 | } | |
952 | if (struct_v >= 3) { | |
953 | decode(hostnames_s3website, bl); | |
954 | } | |
955 | if (struct_v >= 4) { | |
956 | RGWSystemMetaObj::decode(bl); | |
957 | decode(realm_id, bl); | |
958 | } else { | |
959 | id = name; | |
960 | } | |
9f95a23c TL |
961 | if (struct_v >= 5) { |
962 | decode(sync_policy, bl); | |
963 | } | |
11fdf7f2 TL |
964 | DECODE_FINISH(bl); |
965 | } | |
966 | ||
b3b6e05e TL |
967 | int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override; |
968 | int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override; | |
969 | int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false); | |
11fdf7f2 | 970 | int equals(const std::string& other_zonegroup) const; |
b3b6e05e TL |
971 | int add_zone(const DoutPrefixProvider *dpp, |
972 | const RGWZoneParams& zone_params, bool *is_master, bool *read_only, | |
20effc67 TL |
973 | const std::list<std::string>& endpoints, const std::string *ptier_type, |
974 | bool *psync_from_all, std::list<std::string>& sync_from, | |
975 | std::list<std::string>& sync_from_rm, std::string *predirect_zone, | |
f67539c2 TL |
976 | std::optional<int> bucket_index_max_shards, RGWSyncModulesManager *sync_mgr, |
977 | optional_yield y); | |
b3b6e05e TL |
978 | int remove_zone(const DoutPrefixProvider *dpp, const std::string& zone_id, optional_yield y); |
979 | int rename_zone(const DoutPrefixProvider *dpp, const RGWZoneParams& zone_params, optional_yield y); | |
11fdf7f2 TL |
980 | rgw_pool get_pool(CephContext *cct) const override; |
981 | const std::string get_default_oid(bool old_region_format = false) const override; | |
982 | const std::string& get_info_oid_prefix(bool old_region_format = false) const override; | |
983 | const std::string& get_names_oid_prefix() const override; | |
20effc67 | 984 | std::string get_predefined_id(CephContext *cct) const override; |
11fdf7f2 TL |
985 | const std::string& get_predefined_name(CephContext *cct) const override; |
986 | ||
987 | void dump(Formatter *f) const; | |
988 | void decode_json(JSONObj *obj); | |
20effc67 | 989 | static void generate_test_instances(std::list<RGWZoneGroup*>& o); |
11fdf7f2 TL |
990 | }; |
991 | WRITE_CLASS_ENCODER(RGWZoneGroup) | |
992 | ||
993 | struct RGWPeriodMap | |
994 | { | |
995 | std::string id; | |
20effc67 TL |
996 | std::map<std::string, RGWZoneGroup> zonegroups; |
997 | std::map<std::string, RGWZoneGroup> zonegroups_by_api; | |
998 | std::map<std::string, uint32_t> short_zone_ids; | |
11fdf7f2 TL |
999 | |
1000 | std::string master_zonegroup; | |
1001 | ||
1002 | void encode(bufferlist& bl) const; | |
1003 | void decode(bufferlist::const_iterator& bl); | |
1004 | ||
1005 | int update(const RGWZoneGroup& zonegroup, CephContext *cct); | |
1006 | ||
1007 | void dump(Formatter *f) const; | |
1008 | void decode_json(JSONObj *obj); | |
1009 | ||
1010 | void reset() { | |
1011 | zonegroups.clear(); | |
1012 | zonegroups_by_api.clear(); | |
1013 | master_zonegroup.clear(); | |
1014 | } | |
1015 | ||
1016 | uint32_t get_zone_short_id(const std::string& zone_id) const; | |
20effc67 TL |
1017 | |
1018 | bool find_zone_by_id(const rgw_zone_id& zone_id, | |
1019 | RGWZoneGroup *zonegroup, | |
1020 | RGWZone *zone) const; | |
1021 | bool find_zone_by_name(const std::string& zone_id, | |
1022 | RGWZoneGroup *zonegroup, | |
1023 | RGWZone *zone) const; | |
11fdf7f2 TL |
1024 | }; |
1025 | WRITE_CLASS_ENCODER(RGWPeriodMap) | |
1026 | ||
1027 | struct RGWPeriodConfig | |
1028 | { | |
1029 | RGWQuotaInfo bucket_quota; | |
1030 | RGWQuotaInfo user_quota; | |
20effc67 TL |
1031 | RGWRateLimitInfo user_ratelimit; |
1032 | RGWRateLimitInfo bucket_ratelimit; | |
1033 | // rate limit unauthenticated user | |
1034 | RGWRateLimitInfo anon_ratelimit; | |
11fdf7f2 TL |
1035 | |
1036 | void encode(bufferlist& bl) const { | |
20effc67 | 1037 | ENCODE_START(2, 1, bl); |
11fdf7f2 TL |
1038 | encode(bucket_quota, bl); |
1039 | encode(user_quota, bl); | |
20effc67 TL |
1040 | encode(bucket_ratelimit, bl); |
1041 | encode(user_ratelimit, bl); | |
1042 | encode(anon_ratelimit, bl); | |
11fdf7f2 TL |
1043 | ENCODE_FINISH(bl); |
1044 | } | |
1045 | ||
1046 | void decode(bufferlist::const_iterator& bl) { | |
20effc67 | 1047 | DECODE_START(2, bl); |
11fdf7f2 TL |
1048 | decode(bucket_quota, bl); |
1049 | decode(user_quota, bl); | |
20effc67 TL |
1050 | if (struct_v >= 2) { |
1051 | decode(bucket_ratelimit, bl); | |
1052 | decode(user_ratelimit, bl); | |
1053 | decode(anon_ratelimit, bl); | |
1054 | } | |
11fdf7f2 TL |
1055 | DECODE_FINISH(bl); |
1056 | } | |
1057 | ||
1058 | void dump(Formatter *f) const; | |
1059 | void decode_json(JSONObj *obj); | |
1060 | ||
1061 | // the period config must be stored in a local object outside of the period, | |
1062 | // so that it can be used in a default configuration where no realm/period | |
1063 | // exists | |
b3b6e05e TL |
1064 | int read(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y); |
1065 | int write(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y); | |
11fdf7f2 TL |
1066 | |
1067 | static std::string get_oid(const std::string& realm_id); | |
1068 | static rgw_pool get_pool(CephContext *cct); | |
1069 | }; | |
1070 | WRITE_CLASS_ENCODER(RGWPeriodConfig) | |
1071 | ||
1072 | /* for backward comaptability */ | |
1073 | struct RGWRegionMap { | |
1074 | ||
20effc67 | 1075 | std::map<std::string, RGWZoneGroup> regions; |
11fdf7f2 TL |
1076 | |
1077 | std::string master_region; | |
1078 | ||
1079 | RGWQuotaInfo bucket_quota; | |
1080 | RGWQuotaInfo user_quota; | |
1081 | ||
1082 | void encode(bufferlist& bl) const; | |
1083 | void decode(bufferlist::const_iterator& bl); | |
1084 | ||
1085 | void dump(Formatter *f) const; | |
1086 | void decode_json(JSONObj *obj); | |
1087 | }; | |
1088 | WRITE_CLASS_ENCODER(RGWRegionMap) | |
1089 | ||
1090 | struct RGWZoneGroupMap { | |
1091 | ||
20effc67 TL |
1092 | std::map<std::string, RGWZoneGroup> zonegroups; |
1093 | std::map<std::string, RGWZoneGroup> zonegroups_by_api; | |
11fdf7f2 TL |
1094 | |
1095 | std::string master_zonegroup; | |
1096 | ||
1097 | RGWQuotaInfo bucket_quota; | |
1098 | RGWQuotaInfo user_quota; | |
1099 | ||
1100 | /* construct the map */ | |
b3b6e05e | 1101 | int read(const DoutPrefixProvider *dpp, CephContext *cct, RGWSI_SysObj *sysobj_svc, optional_yield y); |
11fdf7f2 TL |
1102 | |
1103 | void encode(bufferlist& bl) const; | |
1104 | void decode(bufferlist::const_iterator& bl); | |
1105 | ||
1106 | void dump(Formatter *f) const; | |
1107 | void decode_json(JSONObj *obj); | |
1108 | }; | |
1109 | WRITE_CLASS_ENCODER(RGWZoneGroupMap) | |
1110 | ||
1111 | class RGWRealm; | |
1112 | class RGWPeriod; | |
1113 | ||
1114 | class RGWRealm : public RGWSystemMetaObj | |
1115 | { | |
1116 | std::string current_period; | |
1117 | epoch_t epoch{0}; //< realm epoch, incremented for each new period | |
1118 | ||
b3b6e05e TL |
1119 | int create_control(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y); |
1120 | int delete_control(const DoutPrefixProvider *dpp, optional_yield y); | |
11fdf7f2 TL |
1121 | public: |
1122 | RGWRealm() {} | |
1123 | RGWRealm(const std::string& _id, const std::string& _name = "") : RGWSystemMetaObj(_id, _name) {} | |
1124 | RGWRealm(CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_cct, _sysobj_svc) {} | |
1125 | RGWRealm(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_name, _cct, _sysobj_svc){} | |
20effc67 | 1126 | virtual ~RGWRealm() override; |
11fdf7f2 TL |
1127 | |
1128 | void encode(bufferlist& bl) const override { | |
1129 | ENCODE_START(1, 1, bl); | |
1130 | RGWSystemMetaObj::encode(bl); | |
1131 | encode(current_period, bl); | |
1132 | encode(epoch, bl); | |
1133 | ENCODE_FINISH(bl); | |
1134 | } | |
1135 | ||
1136 | void decode(bufferlist::const_iterator& bl) override { | |
1137 | DECODE_START(1, bl); | |
1138 | RGWSystemMetaObj::decode(bl); | |
1139 | decode(current_period, bl); | |
1140 | decode(epoch, bl); | |
1141 | DECODE_FINISH(bl); | |
1142 | } | |
1143 | ||
b3b6e05e TL |
1144 | int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override; |
1145 | int delete_obj(const DoutPrefixProvider *dpp, optional_yield y); | |
11fdf7f2 TL |
1146 | rgw_pool get_pool(CephContext *cct) const override; |
1147 | const std::string get_default_oid(bool old_format = false) const override; | |
1148 | const std::string& get_names_oid_prefix() const override; | |
1149 | const std::string& get_info_oid_prefix(bool old_format = false) const override; | |
20effc67 | 1150 | std::string get_predefined_id(CephContext *cct) const override; |
11fdf7f2 TL |
1151 | const std::string& get_predefined_name(CephContext *cct) const override; |
1152 | ||
1153 | using RGWSystemMetaObj::read_id; // expose as public for radosgw-admin | |
1154 | ||
1155 | void dump(Formatter *f) const; | |
1156 | void decode_json(JSONObj *obj); | |
20effc67 | 1157 | static void generate_test_instances(std::list<RGWRealm*>& o); |
11fdf7f2 TL |
1158 | |
1159 | const std::string& get_current_period() const { | |
1160 | return current_period; | |
1161 | } | |
b3b6e05e | 1162 | int set_current_period(const DoutPrefixProvider *dpp, RGWPeriod& period, optional_yield y); |
11fdf7f2 TL |
1163 | void clear_current_period_and_epoch() { |
1164 | current_period.clear(); | |
1165 | epoch = 0; | |
1166 | } | |
1167 | epoch_t get_epoch() const { return epoch; } | |
1168 | ||
1169 | std::string get_control_oid() const; | |
1170 | /// send a notify on the realm control object | |
b3b6e05e | 1171 | int notify_zone(const DoutPrefixProvider *dpp, bufferlist& bl, optional_yield y); |
11fdf7f2 | 1172 | /// notify the zone of a new period |
b3b6e05e | 1173 | int notify_new_period(const DoutPrefixProvider *dpp, const RGWPeriod& period, optional_yield y); |
20effc67 TL |
1174 | |
1175 | int find_zone(const DoutPrefixProvider *dpp, | |
1176 | const rgw_zone_id& zid, | |
1177 | RGWPeriod *pperiod, | |
1178 | RGWZoneGroup *pzonegroup, | |
1179 | bool *pfound, | |
1180 | optional_yield y) const; | |
11fdf7f2 TL |
1181 | }; |
1182 | WRITE_CLASS_ENCODER(RGWRealm) | |
1183 | ||
1184 | struct RGWPeriodLatestEpochInfo { | |
9f95a23c | 1185 | epoch_t epoch = 0; |
11fdf7f2 TL |
1186 | |
1187 | void encode(bufferlist& bl) const { | |
1188 | ENCODE_START(1, 1, bl); | |
1189 | encode(epoch, bl); | |
1190 | ENCODE_FINISH(bl); | |
1191 | } | |
1192 | ||
1193 | void decode(bufferlist::const_iterator& bl) { | |
1194 | DECODE_START(1, bl); | |
1195 | decode(epoch, bl); | |
1196 | DECODE_FINISH(bl); | |
1197 | } | |
1198 | ||
1199 | void dump(Formatter *f) const; | |
1200 | void decode_json(JSONObj *obj); | |
20effc67 | 1201 | static void generate_test_instances(std::list<RGWPeriodLatestEpochInfo*>& o); |
11fdf7f2 TL |
1202 | }; |
1203 | WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo) | |
1204 | ||
9f95a23c TL |
1205 | |
1206 | /* | |
1207 | * The RGWPeriod object contains the entire configuration of a | |
1208 | * RGWRealm, including its RGWZoneGroups and RGWZones. Consistency of | |
1209 | * this configuration is maintained across all zones by passing around | |
1210 | * the RGWPeriod object in its JSON representation. | |
1211 | * | |
1212 | * If a new configuration changes which zone is the metadata master | |
1213 | * zone (i.e., master zone of the master zonegroup), then a new | |
1214 | * RGWPeriod::id (a uuid) is generated, its RGWPeriod::realm_epoch is | |
1215 | * incremented, and the RGWRealm object is updated to reflect that new | |
1216 | * current_period id and epoch. If the configuration changes BUT which | |
1217 | * zone is the metadata master does NOT change, then only the | |
1218 | * RGWPeriod::epoch is incremented (and the RGWPeriod::id remains the | |
1219 | * same). | |
1220 | * | |
1221 | * When a new RGWPeriod is created with a new RGWPeriod::id (uuid), it | |
1222 | * is linked back to its predecessor RGWPeriod through the | |
1223 | * RGWPeriod::predecessor_uuid field, thus creating a "linked | |
1224 | * list"-like structure of RGWPeriods back to the cluster's creation. | |
1225 | */ | |
11fdf7f2 TL |
1226 | class RGWPeriod |
1227 | { | |
9f95a23c | 1228 | std::string id; //< a uuid |
11fdf7f2 TL |
1229 | epoch_t epoch{0}; |
1230 | std::string predecessor_uuid; | |
1231 | std::vector<std::string> sync_status; | |
1232 | RGWPeriodMap period_map; | |
1233 | RGWPeriodConfig period_config; | |
1234 | std::string master_zonegroup; | |
9f95a23c | 1235 | rgw_zone_id master_zone; |
11fdf7f2 TL |
1236 | |
1237 | std::string realm_id; | |
1238 | std::string realm_name; | |
1239 | epoch_t realm_epoch{1}; //< realm epoch when period was made current | |
1240 | ||
1241 | CephContext *cct{nullptr}; | |
1242 | RGWSI_SysObj *sysobj_svc{nullptr}; | |
1243 | ||
b3b6e05e TL |
1244 | int read_info(const DoutPrefixProvider *dpp, optional_yield y); |
1245 | int read_latest_epoch(const DoutPrefixProvider *dpp, | |
1246 | RGWPeriodLatestEpochInfo& epoch_info, | |
f67539c2 | 1247 | optional_yield y, |
11fdf7f2 | 1248 | RGWObjVersionTracker *objv = nullptr); |
b3b6e05e | 1249 | int use_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y); |
11fdf7f2 TL |
1250 | int use_current_period(); |
1251 | ||
1252 | const std::string get_period_oid() const; | |
1253 | const std::string get_period_oid_prefix() const; | |
1254 | ||
1255 | // gather the metadata sync status for each shard; only for use on master zone | |
20effc67 TL |
1256 | int update_sync_status(const DoutPrefixProvider *dpp, |
1257 | rgw::sal::Store* store, | |
11fdf7f2 TL |
1258 | const RGWPeriod ¤t_period, |
1259 | std::ostream& error_stream, bool force_if_stale); | |
1260 | ||
1261 | public: | |
1262 | RGWPeriod() {} | |
1263 | ||
9f95a23c | 1264 | explicit RGWPeriod(const std::string& period_id, epoch_t _epoch = 0) |
11fdf7f2 TL |
1265 | : id(period_id), epoch(_epoch) {} |
1266 | ||
1267 | const std::string& get_id() const { return id; } | |
1268 | epoch_t get_epoch() const { return epoch; } | |
1269 | epoch_t get_realm_epoch() const { return realm_epoch; } | |
1270 | const std::string& get_predecessor() const { return predecessor_uuid; } | |
9f95a23c | 1271 | const rgw_zone_id& get_master_zone() const { return master_zone; } |
11fdf7f2 TL |
1272 | const std::string& get_master_zonegroup() const { return master_zonegroup; } |
1273 | const std::string& get_realm() const { return realm_id; } | |
20effc67 | 1274 | const std::string& get_realm_name() const { return realm_name; } |
11fdf7f2 TL |
1275 | const RGWPeriodMap& get_map() const { return period_map; } |
1276 | RGWPeriodConfig& get_config() { return period_config; } | |
1277 | const RGWPeriodConfig& get_config() const { return period_config; } | |
1278 | const std::vector<std::string>& get_sync_status() const { return sync_status; } | |
1279 | rgw_pool get_pool(CephContext *cct) const; | |
1280 | const std::string& get_latest_epoch_oid() const; | |
1281 | const std::string& get_info_oid_prefix() const; | |
1282 | ||
1283 | void set_user_quota(RGWQuotaInfo& user_quota) { | |
1284 | period_config.user_quota = user_quota; | |
1285 | } | |
1286 | ||
1287 | void set_bucket_quota(RGWQuotaInfo& bucket_quota) { | |
1288 | period_config.bucket_quota = bucket_quota; | |
1289 | } | |
1290 | ||
20effc67 | 1291 | void set_id(const std::string& _id) { |
9f95a23c TL |
1292 | this->id = _id; |
1293 | period_map.id = _id; | |
11fdf7f2 TL |
1294 | } |
1295 | void set_epoch(epoch_t epoch) { this->epoch = epoch; } | |
1296 | void set_realm_epoch(epoch_t epoch) { realm_epoch = epoch; } | |
1297 | ||
1298 | void set_predecessor(const std::string& predecessor) | |
1299 | { | |
1300 | predecessor_uuid = predecessor; | |
1301 | } | |
1302 | ||
1303 | void set_realm_id(const std::string& _realm_id) { | |
1304 | realm_id = _realm_id; | |
1305 | } | |
1306 | ||
b3b6e05e | 1307 | int reflect(const DoutPrefixProvider *dpp, optional_yield y); |
11fdf7f2 TL |
1308 | |
1309 | int get_zonegroup(RGWZoneGroup& zonegroup, | |
1310 | const std::string& zonegroup_id) const; | |
1311 | ||
1312 | bool is_single_zonegroup() const | |
1313 | { | |
9f95a23c | 1314 | return (period_map.zonegroups.size() <= 1); |
11fdf7f2 TL |
1315 | } |
1316 | ||
1317 | /* | |
1318 | returns true if there are several zone groups with a least one zone | |
1319 | */ | |
1320 | bool is_multi_zonegroups_with_zones() const | |
1321 | { | |
1322 | int count = 0; | |
1323 | for (const auto& zg: period_map.zonegroups) { | |
1324 | if (zg.second.zones.size() > 0) { | |
1325 | if (count++ > 0) { | |
1326 | return true; | |
1327 | } | |
1328 | } | |
1329 | } | |
1330 | return false; | |
1331 | } | |
1332 | ||
20effc67 TL |
1333 | bool find_zone(const DoutPrefixProvider *dpp, |
1334 | const rgw_zone_id& zid, | |
1335 | RGWZoneGroup *pzonegroup, | |
1336 | optional_yield y) const; | |
1337 | ||
b3b6e05e TL |
1338 | int get_latest_epoch(const DoutPrefixProvider *dpp, epoch_t& epoch, optional_yield y); |
1339 | int set_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y, | |
f67539c2 | 1340 | epoch_t epoch, bool exclusive = false, |
11fdf7f2 TL |
1341 | RGWObjVersionTracker *objv = nullptr); |
1342 | // update latest_epoch if the given epoch is higher, else return -EEXIST | |
b3b6e05e | 1343 | int update_latest_epoch(const DoutPrefixProvider *dpp, epoch_t epoch, optional_yield y); |
11fdf7f2 | 1344 | |
b3b6e05e | 1345 | int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, const std::string &period_realm_id, optional_yield y, |
f67539c2 | 1346 | const std::string &period_realm_name = "", bool setup_obj = true); |
b3b6e05e | 1347 | int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y, bool setup_obj = true); |
11fdf7f2 | 1348 | |
b3b6e05e TL |
1349 | int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true); |
1350 | int delete_obj(const DoutPrefixProvider *dpp, optional_yield y); | |
1351 | int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y); | |
1352 | int add_zonegroup(const DoutPrefixProvider *dpp, const RGWZoneGroup& zonegroup, optional_yield y); | |
11fdf7f2 TL |
1353 | |
1354 | void fork(); | |
b3b6e05e | 1355 | int update(const DoutPrefixProvider *dpp, optional_yield y); |
11fdf7f2 TL |
1356 | |
1357 | // commit a staging period; only for use on master zone | |
20effc67 TL |
1358 | int commit(const DoutPrefixProvider *dpp, |
1359 | rgw::sal::Store* store, | |
11fdf7f2 | 1360 | RGWRealm& realm, const RGWPeriod ¤t_period, |
f67539c2 TL |
1361 | std::ostream& error_stream, optional_yield y, |
1362 | bool force_if_stale = false); | |
11fdf7f2 TL |
1363 | |
1364 | void encode(bufferlist& bl) const { | |
1365 | ENCODE_START(1, 1, bl); | |
1366 | encode(id, bl); | |
1367 | encode(epoch, bl); | |
1368 | encode(realm_epoch, bl); | |
1369 | encode(predecessor_uuid, bl); | |
1370 | encode(sync_status, bl); | |
1371 | encode(period_map, bl); | |
1372 | encode(master_zone, bl); | |
1373 | encode(master_zonegroup, bl); | |
1374 | encode(period_config, bl); | |
1375 | encode(realm_id, bl); | |
1376 | encode(realm_name, bl); | |
1377 | ENCODE_FINISH(bl); | |
1378 | } | |
1379 | ||
1380 | void decode(bufferlist::const_iterator& bl) { | |
1381 | DECODE_START(1, bl); | |
1382 | decode(id, bl); | |
1383 | decode(epoch, bl); | |
1384 | decode(realm_epoch, bl); | |
1385 | decode(predecessor_uuid, bl); | |
1386 | decode(sync_status, bl); | |
1387 | decode(period_map, bl); | |
1388 | decode(master_zone, bl); | |
1389 | decode(master_zonegroup, bl); | |
1390 | decode(period_config, bl); | |
1391 | decode(realm_id, bl); | |
1392 | decode(realm_name, bl); | |
1393 | DECODE_FINISH(bl); | |
1394 | } | |
1395 | void dump(Formatter *f) const; | |
1396 | void decode_json(JSONObj *obj); | |
20effc67 | 1397 | static void generate_test_instances(std::list<RGWPeriod*>& o); |
11fdf7f2 TL |
1398 | |
1399 | static std::string get_staging_id(const std::string& realm_id) { | |
1400 | return realm_id + ":staging"; | |
1401 | } | |
1402 | }; | |
1403 | WRITE_CLASS_ENCODER(RGWPeriod) | |
1404 | ||
1405 | #endif |