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