]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_sync_policy.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rgw / rgw_sync_policy.h
CommitLineData
9f95a23c
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4/*
5 * Ceph - scalable distributed file system
6 *
7 * Copyright (C) 2018 Red Hat, Inc.
8 *
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
13 *
14 */
15
16#pragma once
17
18#include "rgw_basic_types.h"
f67539c2 19#include "rgw_tag.h"
9f95a23c
TL
20
21
22struct rgw_sync_symmetric_group {
23 string id;
24 std::set<rgw_zone_id> zones;
25
26 rgw_sync_symmetric_group() {}
27 rgw_sync_symmetric_group(const string& _id,
28 const std::set<rgw_zone_id> _zones) : id(_id), zones(_zones) {}
29
30
31 void encode(bufferlist& bl) const {
32 ENCODE_START(1, 1, bl);
33 encode(id, bl);
34 encode(zones, bl);
35 ENCODE_FINISH(bl);
36 }
37
38 void decode(bufferlist::const_iterator& bl) {
39 DECODE_START(1, bl);
40 decode(id, bl);
41 decode(zones, bl);
42 DECODE_FINISH(bl);
43 }
44
45 void dump(ceph::Formatter *f) const;
46 void decode_json(JSONObj *obj);
47};
48WRITE_CLASS_ENCODER(rgw_sync_symmetric_group)
49
50struct rgw_sync_directional_rule {
51 rgw_zone_id source_zone;
52 rgw_zone_id dest_zone;
53
54 void encode(bufferlist& bl) const {
55 ENCODE_START(1, 1, bl);
56 encode(source_zone, bl);
57 encode(dest_zone, bl);
58 ENCODE_FINISH(bl);
59 }
60
61 void decode(bufferlist::const_iterator& bl) {
62 DECODE_START(1, bl);
63 decode(source_zone, bl);
64 decode(dest_zone, bl);
65 DECODE_FINISH(bl);
66 }
67
68 void dump(ceph::Formatter *f) const;
69 void decode_json(JSONObj *obj);
70};
71WRITE_CLASS_ENCODER(rgw_sync_directional_rule)
72
73struct rgw_sync_bucket_entity {
74 std::optional<rgw_zone_id> zone; /* define specific zones */
75 std::optional<rgw_bucket> bucket; /* define specific bucket */
76
77 static bool match_str(const string& s1, const string& s2) { /* empty string is wildcard */
78 return (s1.empty() ||
79 s2.empty() ||
80 s1 == s2);
81 }
82
83 bool all_zones{false};
84
85 rgw_sync_bucket_entity() {}
86 rgw_sync_bucket_entity(const rgw_zone_id& _zone,
87 std::optional<rgw_bucket> _bucket) : zone(_zone),
88 bucket(_bucket.value_or(rgw_bucket())) {}
89
90 bool specific() const {
91 return zone && bucket;
92 }
93
94 void encode(bufferlist& bl) const {
95 ENCODE_START(1, 1, bl);
96 encode(all_zones, bl);
97 encode(zone, bl);
98 encode(bucket, bl);
99 ENCODE_FINISH(bl);
100 }
101
102 void decode(bufferlist::const_iterator& bl) {
103 DECODE_START(1, bl);
104 decode(all_zones, bl);
105 decode(zone, bl);
106 decode(bucket, bl);
107 DECODE_FINISH(bl);
108 }
109
110 void dump(ceph::Formatter *f) const;
111 void decode_json(JSONObj *obj);
112
113 rgw_bucket get_bucket() const {
114 return bucket.value_or(rgw_bucket());
115 }
116
117 string bucket_key() const;
118
119 bool match_zone(const rgw_zone_id& z) const {
120 if (all_zones) {
121 return true;
122 }
123 if (!zone) {
124 return false;
125 }
126
127 return (*zone == z);
128 }
129
130 void apply_zone(const rgw_zone_id& z) {
131 all_zones = false;
132 zone = z;
133 }
134
135 static bool match_bucket_id(const string& bid1, const string& bid2) {
136 return (bid1.empty() || bid2.empty() || (bid1 == bid2));
137 }
138
139 bool match_bucket(std::optional<rgw_bucket> b) const {
140 if (!b) {
141 return true;
142 }
143
144 if (!bucket) {
145 return true;
146 }
147
148 return (match_str(bucket->tenant, b->tenant) &&
149 match_str(bucket->name, b->name) &&
150 match_bucket_id(bucket->bucket_id, b->bucket_id));
151 }
152
153 bool match(const rgw_sync_bucket_entity& entity) const {
154 if (!entity.zone) {
155 return match_bucket(entity.bucket);
156 }
157 return (match_zone(*entity.zone) && match_bucket(entity.bucket));
158 }
159
160 const bool operator<(const rgw_sync_bucket_entity& e) const {
161 if (all_zones && !e.all_zones) {
162 return false;
163 }
164 if (!all_zones && e.all_zones) {
165 return true;
166 }
167 if (zone < e.zone) {
168 return true;
169 }
170 if (e.zone < zone) {
171 return false;
172 }
173 return (bucket < e.bucket);
174 }
175
176 void apply_bucket(std::optional<rgw_bucket> _b);
177};
178WRITE_CLASS_ENCODER(rgw_sync_bucket_entity)
179
180struct rgw_sync_pipe_filter_tag {
181 string key;
182 string value;
183
184 rgw_sync_pipe_filter_tag() {}
185 rgw_sync_pipe_filter_tag(const string& s) {
186 from_str(s);
187 }
188 rgw_sync_pipe_filter_tag(const string& _key,
189 const string& _value) : key(_key),
190 value(_value) {}
191
192 void encode(bufferlist& bl) const {
193 ENCODE_START(1, 1, bl);
194 encode(key, bl);
195 encode(value, bl);
196 ENCODE_FINISH(bl);
197 }
198
199 void decode(bufferlist::const_iterator& bl) {
200 DECODE_START(1, bl);
201 decode(key, bl);
202 decode(value, bl);
203 DECODE_FINISH(bl);
204 }
205
206 void dump(ceph::Formatter *f) const;
207 void decode_json(JSONObj *obj);
208
209 bool from_str(const string& s);
210
211 bool operator<(const rgw_sync_pipe_filter_tag& t) const {
212 if (key < t.key) {
213 return true;
214 }
215 if (t.key < key) {
216 return false;
217 }
218 return (value < t.value);
219 }
220
221 bool operator==(const string& s) const;
222};
223WRITE_CLASS_ENCODER(rgw_sync_pipe_filter_tag)
224
225struct rgw_sync_pipe_filter {
226 std::optional<string> prefix;
227 std::set<rgw_sync_pipe_filter_tag> tags;
228
229 void set_prefix(std::optional<std::string> opt_prefix,
230 bool prefix_rm);
231 void set_tags(std::list<std::string>& tags_add,
232 std::list<std::string>& tags_rm);
233
234 void encode(bufferlist& bl) const;
235 void decode(bufferlist::const_iterator& bl);
236
237 void dump(ceph::Formatter *f) const;
238 void decode_json(JSONObj *obj);
239
240 bool is_subset_of(const rgw_sync_pipe_filter& f) const;
241
242 bool has_tags() const;
243 bool check_tag(const string& s) const;
244 bool check_tag(const string& k, const string& v) const;
245 bool check_tags(const std::vector<string>& tags) const;
246 bool check_tags(const RGWObjTags::tag_map_t& tags) const;
247};
248WRITE_CLASS_ENCODER(rgw_sync_pipe_filter)
249
250struct rgw_sync_pipe_acl_translation {
251 rgw_user owner;
252
253 void encode(bufferlist& bl) const {
254 ENCODE_START(1, 1, bl);
255 encode(owner, bl);
256 ENCODE_FINISH(bl);
257 }
258
259 void decode(bufferlist::const_iterator& bl) {
260 DECODE_START(1, bl);
261 decode(owner, bl);
262 DECODE_FINISH(bl);
263 }
264
265 void dump(ceph::Formatter *f) const;
266 void decode_json(JSONObj *obj);
267
268 bool operator==(const rgw_sync_pipe_acl_translation& aclt) const {
269 return (owner == aclt.owner);
270 }
271};
272WRITE_CLASS_ENCODER(rgw_sync_pipe_acl_translation)
273
274struct rgw_sync_pipe_source_params {
275 rgw_sync_pipe_filter filter;
276
277 void encode(bufferlist& bl) const {
278 ENCODE_START(1, 1, bl);
279 encode(filter, bl);
280 ENCODE_FINISH(bl);
281 }
282
283 void decode(bufferlist::const_iterator& bl) {
284 DECODE_START(1, bl);
285 decode(filter, bl);
286 DECODE_FINISH(bl);
287 }
288
289 void dump(ceph::Formatter *f) const;
290 void decode_json(JSONObj *obj);
291};
292WRITE_CLASS_ENCODER(rgw_sync_pipe_source_params)
293
294struct rgw_sync_pipe_dest_params {
295 std::optional<rgw_sync_pipe_acl_translation> acl_translation;
296 std::optional<string> storage_class;
297
298 void encode(bufferlist& bl) const {
299 ENCODE_START(1, 1, bl);
300 encode(acl_translation, bl);
301 encode(storage_class, bl);
302 ENCODE_FINISH(bl);
303 }
304
305 void decode(bufferlist::const_iterator& bl) {
306 DECODE_START(1, bl);
307 decode(acl_translation, bl);
308 decode(storage_class, bl);
309 DECODE_FINISH(bl);
310 }
311
312 void set_storage_class(const string& sc) {
313 storage_class = sc;
314 }
315
316 void set_owner(const rgw_user& owner) {
317 if (owner.empty()){
318 acl_translation.reset();
319 } else {
320 acl_translation.emplace();
321 acl_translation->owner = owner;
322 }
323 }
324
325 void dump(ceph::Formatter *f) const;
326 void decode_json(JSONObj *obj);
327
328 bool operator==(const rgw_sync_pipe_dest_params& rhs) const {
329 return (acl_translation == rhs.acl_translation &&
330 storage_class == rhs.storage_class);
331 }
332};
333WRITE_CLASS_ENCODER(rgw_sync_pipe_dest_params)
334
335struct rgw_sync_pipe_params {
336 rgw_sync_pipe_source_params source;
337 rgw_sync_pipe_dest_params dest;
338 enum Mode {
339 MODE_SYSTEM = 0,
340 MODE_USER = 1,
341 } mode{MODE_SYSTEM};
342 int32_t priority{0};
343 rgw_user user;
344
345 void encode(bufferlist& bl) const {
346 ENCODE_START(1, 1, bl);
347 encode(source, bl);
348 encode(dest, bl);
349 encode(priority, bl);
350 encode((uint8_t)mode, bl);
351 encode(user, bl);
352 ENCODE_FINISH(bl);
353 }
354
355 void decode(bufferlist::const_iterator& bl) {
356 DECODE_START(1, bl);
357 decode(source, bl);
358 decode(dest, bl);
359 decode(priority, bl);
360 uint8_t m;
361 decode(m, bl);
362 mode = (Mode)m;
363 decode(user, bl);
364 DECODE_FINISH(bl);
365 }
366
367 void dump(ceph::Formatter *f) const;
368 void decode_json(JSONObj *obj);
369};
370WRITE_CLASS_ENCODER(rgw_sync_pipe_params)
371
372struct rgw_sync_bucket_pipe {
373 string id;
374 rgw_sync_bucket_entity source;
375 rgw_sync_bucket_entity dest;
376
377 rgw_sync_pipe_params params;
378
379 bool specific() const {
380 return source.specific() && dest.specific();
381 }
382
383 void encode(bufferlist& bl) const {
384 ENCODE_START(1, 1, bl);
385 encode(id, bl);
386 encode(source, bl);
387 encode(dest, bl);
388 encode(params, bl);
389 ENCODE_FINISH(bl);
390 }
391
392 void decode(bufferlist::const_iterator& bl) {
393 DECODE_START(1, bl);
394 decode(id, bl);
395 decode(source, bl);
396 decode(dest, bl);
397 decode(params, bl);
398 DECODE_FINISH(bl);
399 }
400
401 const bool operator<(const rgw_sync_bucket_pipe& p) const {
402 if (id < p.id) {
403 return true;
404 }
405 if (id >p.id) {
406 return false;
407 }
408 if (source < p.source) {
409 return true;
410 }
411 if (p.source < source) {
412 return false;
413 }
414 return (dest < p.dest);
415 }
416
417 void dump(ceph::Formatter *f) const;
418 void decode_json(JSONObj *obj);
419};
420WRITE_CLASS_ENCODER(rgw_sync_bucket_pipe)
421
422struct rgw_sync_bucket_entities {
423 std::optional<rgw_bucket> bucket; /* define specific bucket */
424 std::optional<std::set<rgw_zone_id> > zones; /* define specific zones, if not set then all zones */
425
426 bool all_zones{false};
427
428
429 void encode(bufferlist& bl) const {
430 ENCODE_START(1, 1, bl);
431 encode(bucket, bl);
432 encode(zones, bl);
433 encode(all_zones, bl);
434 ENCODE_FINISH(bl);
435 }
436
437 void decode(bufferlist::const_iterator& bl) {
438 DECODE_START(1, bl);
439 decode(bucket, bl);
440 decode(zones, bl);
441 decode(all_zones, bl);
442 DECODE_FINISH(bl);
443 }
444
445 void dump(ceph::Formatter *f) const;
446 void decode_json(JSONObj *obj);
447
448 bool match_bucket(std::optional<rgw_bucket> b) const {
449 if (!b) {
450 return true;
451 }
452
453 if (!bucket) {
454 return true;
455 }
456
457 return (rgw_sync_bucket_entity::match_str(bucket->tenant, b->tenant) &&
458 rgw_sync_bucket_entity::match_str(bucket->name, b->name) &&
459 rgw_sync_bucket_entity::match_str(bucket->bucket_id, b->bucket_id));
460 }
461
462 void add_zones(const std::vector<rgw_zone_id>& new_zones);
463 void remove_zones(const std::vector<rgw_zone_id>& rm_zones);
464 void set_bucket(std::optional<string> tenant,
465 std::optional<string> bucket_name,
466 std::optional<string> bucket_id);
467 void remove_bucket(std::optional<string> tenant,
468 std::optional<string> bucket_name,
469 std::optional<string> bucket_id);
470
471 bool match_zone(const rgw_zone_id& zone) const {
472 if (!zones) {
473 if (all_zones) {
474 return true;
475 }
476 return false;
477 }
478
479 return (zones->find(zone) != zones->end());
480 }
481
482 std::vector<rgw_sync_bucket_entity> expand() const;
483
484 rgw_bucket get_bucket() const {
485 return bucket.value_or(rgw_bucket());
486 }
487
488 static string bucket_key(std::optional<rgw_bucket> b);
489
490 void set_all_zones(bool state) {
491 all_zones = state;
492 if (all_zones) {
493 zones.reset();
494 }
495 }
496};
497WRITE_CLASS_ENCODER(rgw_sync_bucket_entities)
498
499struct rgw_sync_bucket_pipes {
500 string id;
501 rgw_sync_bucket_entities source;
502 rgw_sync_bucket_entities dest;
503
504 rgw_sync_pipe_params params;
505
506 void encode(bufferlist& bl) const {
507 ENCODE_START(1, 1, bl);
508 encode(id, bl);
509 encode(source, bl);
510 encode(dest, bl);
511 encode(params, bl);
512 ENCODE_FINISH(bl);
513 }
514
515 void decode(bufferlist::const_iterator& bl) {
516 DECODE_START(1, bl);
517 decode(id, bl);
518 decode(source, bl);
519 decode(dest, bl);
520 decode(params, bl);
521 DECODE_FINISH(bl);
522 }
523
524 bool match_source(const rgw_zone_id& zone, std::optional<rgw_bucket> b) const {
525 return (source.match_zone(zone) && source.match_bucket(b));
526 }
527
528 bool match_dest(const rgw_zone_id& zone, std::optional<rgw_bucket> b) const {
529 return (dest.match_zone(zone) && dest.match_bucket(b));
530 }
531
532 bool contains_zone_bucket(const rgw_zone_id& zone, std::optional<rgw_bucket> b) const {
533 return (match_source(zone, b) || match_dest(zone, b));
534 }
535
536 void dump(ceph::Formatter *f) const;
537 void decode_json(JSONObj *obj);
538
539 std::vector<rgw_sync_bucket_pipe> expand() const;
540
541 void get_potential_related_buckets(const rgw_bucket& bucket,
542 std::set<rgw_bucket> *sources,
543 std::set<rgw_bucket> *dests) const;
544};
545WRITE_CLASS_ENCODER(rgw_sync_bucket_pipes)
546
547std::ostream& operator<<(std::ostream& os, const rgw_sync_bucket_entity& e);
548std::ostream& operator<<(std::ostream& os, const rgw_sync_bucket_pipe& pipe);
549std::ostream& operator<<(std::ostream& os, const rgw_sync_bucket_entities& e);
550std::ostream& operator<<(std::ostream& os, const rgw_sync_bucket_pipes& pipe);
551
552/*
553 * define data flow between zones. Symmetrical: zones sync from each other.
554 * Directional: one zone fetches data from another.
555 */
556struct rgw_sync_data_flow_group {
557 std::vector<rgw_sync_symmetric_group> symmetrical;
558 std::vector<rgw_sync_directional_rule> directional;
559
560 void encode(bufferlist& bl) const {
561 ENCODE_START(1, 1, bl);
562 encode(symmetrical, bl);
563 encode(directional, bl);
564 ENCODE_FINISH(bl);
565 }
566
567 void decode(bufferlist::const_iterator& bl) {
568 DECODE_START(1, bl);
569 decode(symmetrical, bl);
570 decode(directional, bl);
571 DECODE_FINISH(bl);
572 }
573
574 void dump(ceph::Formatter *f) const;
575 void decode_json(JSONObj *obj);
576
577 bool empty() const {
578 return (symmetrical.empty() && directional.empty());
579 }
580
581 bool find_or_create_symmetrical(const string& flow_id, rgw_sync_symmetric_group **flow_group);
582 void remove_symmetrical(const string& flow_id, std::optional<std::vector<rgw_zone_id> > zones);
583 bool find_or_create_directional(const rgw_zone_id& source_zone, const rgw_zone_id& dest_zone, rgw_sync_directional_rule **flow_group);
584 void remove_directional(const rgw_zone_id& source_zone, const rgw_zone_id& dest_zone);
585
586 void init_default(const std::set<rgw_zone_id>& zones);
587};
588WRITE_CLASS_ENCODER(rgw_sync_data_flow_group)
589
590
591struct rgw_sync_policy_group {
592 string id;
593
594 rgw_sync_data_flow_group data_flow; /* override data flow, howver, will not be able to
595 add new flows that don't exist at higher level */
596 std::vector<rgw_sync_bucket_pipes> pipes; /* if not defined then applies to all
597 buckets (DR sync) */
598
599 enum Status {
600 UNKNOWN = 0, /* ? */
601 FORBIDDEN = 1, /* sync not allowed */
602 ALLOWED = 2, /* sync allowed */
603 ENABLED = 3, /* sync should happen */
604 } status;
605
606 void encode(bufferlist& bl) const {
607 ENCODE_START(1, 1, bl);
608 encode(id, bl);
609 encode(data_flow, bl);
610 encode(pipes, bl);
611 encode((uint32_t)status, bl);
612 ENCODE_FINISH(bl);
613 }
614
615 void decode(bufferlist::const_iterator& bl) {
616 DECODE_START(1, bl);
617 decode(id, bl);
618 decode(data_flow, bl);
619 decode(pipes, bl);
620 uint32_t s;
621 decode(s, bl);
622 status = (Status)s;
623 DECODE_FINISH(bl);
624 }
625
626 void dump(ceph::Formatter *f) const;
627 void decode_json(JSONObj *obj);
628
629 bool set_status(const string& s) {
630 if (s == "forbidden") {
631 status = rgw_sync_policy_group::Status::FORBIDDEN;
632 } else if (s == "allowed") {
633 status = rgw_sync_policy_group::Status::ALLOWED;
634 } else if (s == "enabled") {
635 status = rgw_sync_policy_group::Status::ENABLED;
636 } else {
637 status = rgw_sync_policy_group::Status::UNKNOWN;
638 return false;
639 }
640
641 return true;
642 }
643
644 bool find_pipe(const string& pipe_id, bool create, rgw_sync_bucket_pipes **pipe);
645 void remove_pipe(const string& pipe_id);
646
647 void get_potential_related_buckets(const rgw_bucket& bucket,
648 std::set<rgw_bucket> *sources,
649 std::set<rgw_bucket> *dests) const;
650
651};
652WRITE_CLASS_ENCODER(rgw_sync_policy_group)
653
654struct rgw_sync_policy_info {
655 std::map<string, rgw_sync_policy_group> groups;
656
657 void encode(bufferlist& bl) const {
658 ENCODE_START(1, 1, bl);
659 encode(groups, bl);
660 ENCODE_FINISH(bl);
661 }
662
663 void decode(bufferlist::const_iterator& bl) {
664 DECODE_START(1, bl);
665 decode(groups, bl);
666 DECODE_FINISH(bl);
667 }
668
669 void dump(ceph::Formatter *f) const;
670 void decode_json(JSONObj *obj);
671
672 bool empty() const {
673 return groups.empty();
674 }
675
676 void get_potential_related_buckets(const rgw_bucket& bucket,
677 std::set<rgw_bucket> *sources,
678 std::set<rgw_bucket> *dests) const;
679};
680WRITE_CLASS_ENCODER(rgw_sync_policy_info)
681
682