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