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